#include "widget.h"
#include "ui_widget.h"

#include <functional>
#include <QDebug>

using namespace std;

void test(int num) {
    qDebug() << "test" << num;
}

void test2(string name, int num) {
    qDebug() << "test2" << name.c_str() << num;
}

void test3(string name, string na) {
    qDebug() << name.c_str() << na.c_str();
}

struct Task {
    function<void(string)> func;  //可调用对象成员
};

struct TestStr {
    void func() {
        qDebug() << "TestStr func";
    }
};

Widget::Widget(QWidget* parent)
    : QWidget(parent),
      ui(new Ui::Widget) {
    ui->setupUi(this);
    //function
    auto f1 = function<void(int)>(test);  //模板构造函数，以可调用对象作为参数，生成一个function可调用对象
    f1(1);

    function<void(int)> f2 = test;  //调用的是function的移动构造，构造一个function包装的可调用对象
    f2(2);

    //bind
    auto f3 = std::bind(test, 3);  //将test函数和一个固定参数绑定为一个可调用对象,将一个可调用对象生成另一个可调用对象
    f3();                          //执行这个对象

    auto f4 = std::bind(test2, placeholders::_1, 4);  //placeholders类似于占位符，在可调用对象中传的参数就是实际值,这样就将可调用对象生成了只需要一个参数的可调用对象
    f4("liu");

    //function  bind
    function<void(string)> f5 = std::bind(test2, placeholders::_1, 5);
    f5("jian");

    //作为回调函数使用
    Task t;
    t.func = f5;
    t.func("liujian");

    Task t2;
    t2.func = std::bind(test3, "hello", placeholders::_1);
    t2.func("liujian");

    TestStr          te;
    function<void()> pf = std::bind(&TestStr::func, &te);
    pf();
}

Widget::~Widget() {
    delete ui;
}
